Skip to content

fix(onboarding): members set up with the public ingest key - #2357

Merged
Makisuo merged 19 commits into
mainfrom
fix/onboarding-member-key
Nov 7, 2026
Merged

Makisuo merged 19 commits into
mainfrom
fix/onboarding-member-key

Conversation

@Makisuo

@Makisuo Makisuo commented Nov 7, 2026 •

Copy link
Copy Markdown
Collaborator

Part of the trial onboarding stack:

  1. docs(onboarding): gRPC works on port 443, add a Ruby and Rails guide #2351 docs: gRPC works on port 443, Ruby and Rails guide
  2. fix(onboarding): setup snippets match the docs, the browser card gets the browser SDK #2356: in-app setup snippets
  3. this PR: members set up with the public key
  4. fix(onboarding): see data arrive before the team step, send a test trace from the page #2358: live before team, "Send test trace", plainer copy

Why

Invites join as member, and members could read neither ingest key. The teammate most likely to do the setup hit placeholders and "An admin can copy it from Settings, Ingestion" (engineers could, in fact). The overview setup card said "Ask an org admin for your ingest keys".

Decision: members read the public key

  • GET /v2/ingest_keys/public returns { object, public_key, public_rotated_at }.
  • It is gated by a new permission, ingest_keys:view_public, whose minimum role is member.
  • Engineers and admins still read both keys from GET /v2/ingest_keys, and rolling stays admin-only.

The public key is made to ship in browser bundles. Ingest gives it the same capability as the private key: send telemetry, never read. So handing it to members exposes nothing a visitor to the customer's site can't already see.

What changed

  • New endpoint and permission, with an OpenAPI path entry, the regenerated iOS spec and a line in docs/api-v2.md. The API key scope derives to ingest_keys:read.
  • retrieveSetupKeys (apps/web/src/data/ingest-keys.ts) reads both keys for an engineer and up, and the public key for a member. Only a permission refusal falls back, whether the session check's tagged error or the API's decoded insufficient_permissions envelope. A key store outage stays a failure, so an admin is never handed the public key.
  • Onboarding connect and the overview setup card use it. A member sees the public key in every snippet, plus one line: "This is your org's public key. It works from servers too. For production servers, an engineer or admin can give you the private key from Settings, Ingestion."

Verification

  • config-resources.http.test.ts (API over PGlite): a member key gets the public key from /public and a 403 from /v2/ingest_keys; the public key matches the admin's read.
  • ingest-keys.test.ts (web):
    • a member gets the public key;
    • an engineer gets both;
    • a 403 from the API itself falls back;
    • a 503 stays a failure with no second request.
    • Mutation check: dropping the envelope match fails the 403 test.
  • Scene test: a member's connect step shows the note, and "Build with your agent" copies the public key.
  • openapi.test.ts, policy tests, web and api typecheck, oxlint.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Organization members can retrieve the public ingest key without access to the private key.
    • Setup and onboarding screens show the public key when a member cannot access the private key, with guidance on using it and when to ask an engineer or admin for help.
  • Documentation
    • API documentation now describes the public-key endpoint and access levels for retrieving and rotating ingest keys.

… the browser SDK

The Browser stack card opened the Next.js server snippet filled with the private key. It now
shows MapleBrowser.init with the public key.

Every in-app snippet now follows the docs quickstart: the key lives in the environment, not in a
source file; Node, Python and Java use their zero-code agents; Go wraps the HTTP handler with
otelhttp. Node no longer imports a package it does not install. Java/Kotlin, .NET, Laravel, Ruby,
Rust and Deno get their own setup instead of "see opentelemetry.io".
… hitting a dead end

An invited teammate joins as a member and could not read either key, so the connect step showed
placeholders and "An admin can copy it". GET /v2/ingest_keys/public returns the public key to
any member (new ingest_keys:view_public permission). It is made to ship in browser bundles and
only sends telemetry, so it adds no exposure.

The onboarding connect step and the overview setup card read both keys when they can, and fall
back to the public key, with a line saying who can hand out the private one.
# Conflicts:
#	apps/web/src/page/overview/setup-checklist-command.ts
…Sources shows the install step

The agent prompt carries the key the picked stack uses, so a browser-only stack never hands the
private key to an agent writing frontend code.
A key store outage stays a failure, so an admin is never handed the public key and told to ask
an engineer for the private one. One shared read serves the connect step and the overview card.
@coderabbitai

coderabbitai Bot commented Nov 7, 2026 •

Copy link
Copy Markdown

Explain Change →

No actionable comments were generated in the recent review.

Walkthrough

The API adds a route for organization members to retrieve the public ingest key and its rotation timestamp. Web setup key retrieval falls back to that route after a recognized permission denial. Onboarding and the setup checklist support and display a public-key-only result.

Changes: Ingest key access and setup

Layer / File(s) Summary
Public-key API contract and route
packages/domain/src/http/v2/ingest-keys.ts, packages/domain/src/policy/permissions.ts, apps/api/src/routes/v2/ingest-keys.http.ts, apps/api/src/routes/v2/config-resources.http.test.ts, packages/domain/src/http/v2/openapi.test.ts, docs/api-v2.md, apps/ios/Packages/MapleAPI/Sources/MapleAPI/openapi.json
The API defines the public-key response, grants members the public-key permission, and adds GET /v2/ingest_keys/public. Route and API documentation describe the access levels. Tests cover member access to the public route and denial of the full-key route.
Public-only setup key retrieval
apps/web/src/data/ingest-keys.ts, apps/web/src/data/ingest-keys.test.ts
retrieveSetupKeys returns both keys when permitted. It returns the public key with a null private key after a recognized permission denial. Other failures propagate.
Onboarding key state and guidance
apps/web/src/page/onboarding/quick-start-connect.ts, apps/web/src/page/onboarding/quick-start-view.ts, apps/web/src/page/onboarding/quick-start-agent-prompt.scene.test.ts
Onboarding uses retrieveSetupKeys and accepts a null private key. In that state, the view identifies the public key and the setup prompt uses it. The view also provides guidance for retrieval failures.
Setup checklist key display
apps/web/src/page/overview/setup-checklist.ts, apps/web/src/page/overview/setup-checklist-command.ts, apps/web/src/page/overview/setup-checklist-view.ts, apps/web/src/page/overview/setup-checklist.scene.test.ts
The checklist uses retrieveSetupKeys and accepts a null private key. It displays the public key in that state and updates its retrieval-failure guidance. A scene test covers the public-key label.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Bug fix

Sequence Diagram(s)

sequenceDiagram
  participant SetupView
  participant retrieveSetupKeys
  participant FullKeysRoute
  participant PublicKeyRoute
  SetupView->>retrieveSetupKeys: request setup keys
  retrieveSetupKeys->>FullKeysRoute: request both keys
  FullKeysRoute-->>retrieveSetupKeys: permission denial
  retrieveSetupKeys->>PublicKeyRoute: request public key
  PublicKeyRoute-->>retrieveSetupKeys: public key and rotation timestamp
  retrieveSetupKeys-->>SetupView: public key and null private key
Loading

Possibly related PRs

  • MapleTechLabs/maple#1895: Updates setup documentation with public-key guidance that is also used in this PR’s onboarding and setup flows.

Suggested reviewers: jeremyfunk

Merge Risk: Minimal · up to bb14a

The public-key setup flow is mergeable after normal checks; no actionable issue remains identified.

Pre-merge checks: Passed 5

Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly describes the main change: members can use the public ingest key during onboarding.
Docstring Coverage Passed No eligible functions found in the changed files. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentat…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

No eligible functions found in the changed files. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 0 functions across 14 files. (2 skipped: 2 unsupported.)

Finishing Touches

Generate docstrings

  • Commit to this branch
  • Create a new PR
Generate unit tests (beta)

  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

Recent review info

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 375b1c8d-2930-42fe-91b3-a4a1b18676e3
Commits

Reviewing files that changed from the base of the PR and between afa9c57 and bb14a76.

Files selected for processing: 16

  • apps/api/src/routes/v2/config-resources.http.test.ts
  • apps/api/src/routes/v2/ingest-keys.http.ts
  • apps/ios/Packages/MapleAPI/Sources/MapleAPI/openapi.json
  • apps/web/src/data/ingest-keys.test.ts
  • apps/web/src/data/ingest-keys.ts
  • apps/web/src/page/onboarding/quick-start-agent-prompt.scene.test.ts
  • apps/web/src/page/onboarding/quick-start-connect.ts
  • apps/web/src/page/onboarding/quick-start-view.ts
  • apps/web/src/page/overview/setup-checklist-command.ts
  • apps/web/src/page/overview/setup-checklist-view.ts
  • apps/web/src/page/overview/setup-checklist.scene.test.ts
  • apps/web/src/page/overview/setup-checklist.ts
  • docs/api-v2.md
  • packages/domain/src/http/v2/ingest-keys.ts
  • packages/domain/src/http/v2/openapi.test.ts
  • packages/domain/src/policy/permissions.ts

Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 3 remain after this review.

@maple-review-bot

This comment has been minimized.

@maple-review-bot

This comment has been minimized.

@maple-review-bot maple-review-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 inline note from Maple's review. The score and summary are in the review comment above.

…ee the keys

Settings, Ingestion shows no key to a member, so the note asks an engineer or admin instead of
pointing there. The overview card's member label is covered by a scene test.
@maple-review-bot

This comment has been minimized.

# Conflicts:
#	apps/landing/src/content/docs/agent-tracing.mdx
#	apps/landing/src/content/docs/agent-tracing/microsoft-agent-framework.mdx
#	apps/landing/src/content/docs/getting-started/quickstart.mdx
#	apps/landing/src/content/docs/reference/ingest.md
# Conflicts:
#	apps/web/src/page/settings/ingestion/view.ts
# Conflicts:
#	apps/web/src/page/overview/setup-checklist-view.ts
@maple-review-bot

This comment has been minimized.

Base automatically changed from fix/onboarding-snippets to main November 7, 2026 16:30
…-key

# Conflicts:
#	apps/web/src/page/onboarding/quick-start-agent-prompt.scene.test.ts
#	apps/web/src/page/onboarding/quick-start-connect.ts
@maple-review-bot

maple-review-bot Bot commented Nov 7, 2026 •

Copy link
Copy Markdown

Maple review

🟢 Confidence 10/10 · safe to merge. Widening a credential read to members is gated by a dedicated permission and pinned by API and web tests.
no findings · tests covered · risk high · 1/1 new units observable

Adds a member-readable GET /v2/ingest_keys/public and has the onboarding and overview setup screens fall back to it when the private-key read is refused, so members are no longer dead-ended. The fallback is confined to permission refusals; safe to merge.

  • GET /v2/ingest_keys/public returns public_key under the new ingest_keys:view_public permission
  • retrieveSetupKeys falls back to the public key only when the read is refused
  • The setup card and onboarding snippets show a member the public key, labelled as such

bb14a76 · What was checked, coverage and telemetry details are on the Maple / review check. Reply "won't fix" to dismiss a finding, or mention @maple-review-bot to ask about one.

@Makisuo
Makisuo merged commit efef86a into main Nov 7, 2026
42 checks passed
@Makisuo
Makisuo deleted the fix/onboarding-member-key branch November 7, 2026 16:39
@maple-review-bot

Copy link
Copy Markdown

Maple: after this shipped

⚠️ Something changed after this shipped. Details below.

Deployed to maple-web (production) at 2026-11-07 17:13 UTC as efef86a. Compared the 60 minutes before and after.

New errors since the deploy:

  • HttpClientError (maple-web, 3/h)
Operation Calls/h Errors p95
FetchSetupChecklistKeys 0 → 3 0.0% → 0.0% 0 → 416 ms

Maple looks once, an hour after the first deploy that carries the merge.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant